import { formatTime, getNowDate, toPascalCase, removeLastPipe, isDir, resolvePath, autoMkdir, resolvePagesJsonOutputPath } from './utils'
import { VitePluginOption } from './types'
import { PAGES_JSON_MAPPING_FILE, ROUTER_FILE } from './constant'

const fs = require('fs');
const path = require('path');

function genPageType (routerContent: string) {
	routerContent += `/**\n`
	routerContent += `* 页面样式类型映射\n`
	routerContent += `*/\n`
	routerContent += `export type NavigationBarTextStyle = 'white' | 'black'\n`
	routerContent += `export type NavigationBarShadowColorType = 'grey' | 'blue' | 'green' | 'orange' | 'red' | 'yellow'\n`
	routerContent += `export type NavigationBarShadow = {\n`
	routerContent += `\tcolorType: NavigationBarShadowColorType\n`
	routerContent += `}\n`
	routerContent += `export type NavigationStyle = 'default' | 'custom'\n`
	routerContent += `export type PageOrientation = 'auto' | 'portrait' | 'landscape'\n`
	routerContent += `export type TransparentTitle = 'always' | 'auto' | 'none'\n`
	routerContent += `export type TitlePenetrate = 'YES' | 'NO'\n`
	routerContent += `export type CustomButtonType = 'forward' | 'back' | 'share' | 'favorite' | 'home' | 'menu' | 'close' | 'none'\n`
	routerContent += `export type CustomButton = {\n`
	routerContent += `\ttype?: CustomButtonType\n`
	routerContent += `\tcolor?: string\n`
	routerContent += `\tbackground?: string\n`
	routerContent += `\tbadgeText?: string\n`
	routerContent += `\tcolorPressed?: string\n`
	routerContent += `\tfloat?: string\n`
	routerContent += `\tfontWeight?: string\n`
	routerContent += `\tfontSize?: string\n`
	routerContent += `\tfontSrc?: string\n`
	routerContent += `\tselect?: string\n`
	routerContent += `\ttext?: string\n`
	routerContent += `\twidth?: string\n`
	routerContent += `}\n`
	routerContent += `export type SearchInput = {\n`
	routerContent += `\tautoFocus?: boolean\n`
	routerContent += `\talign?: string\n`
	routerContent += `\tbackgroundColor?: string\n`
	routerContent += `\tborderRadius?: string\n`
	routerContent += `\tplaceholder?: string\n`
	routerContent += `\tplaceholderColor?: string\n`
	routerContent += `\tdisabled?: boolean\n`
	routerContent += `}\n`
	routerContent += `export type TitleNView = {\n`
	routerContent += `\tbackgroundColor?: string\n`
	routerContent += `\tbuttons?: CustomButton[]\n`
	routerContent += `\ttitleColor?: string\n`
	routerContent += `\ttitleText?: string\n`
	routerContent += `\ttitleSize?: string\n`
	routerContent += `\ttype?: string\n`
	routerContent += `\tsearchInput?: SearchInput\n`
	routerContent += `}\n`
	routerContent += `export type PullToRefreshType = 'defaultValue' | 'circle'\n`
	routerContent += `export type PullToRefreshContentcommon = {\n`
	routerContent += `\tcaption?: string\n`
	routerContent += `}\n`
	routerContent += `export type PullToRefresh = {\n`
	routerContent += `\tsupport?: boolean\n`
	routerContent += `\tcolor?: string\n`
	routerContent += `\ttype?: PullToRefreshType\n`
	routerContent += `\theight?: string\n`
	routerContent += `\trange?: string\n`
	routerContent += `\toffset?: string\n`
	routerContent += `\tcontentdown?: PullToRefreshContentcommon\n`
	routerContent += `\tcontentover?: PullToRefreshContentcommon\n`
	routerContent += `\tcontentrefresh?: PullToRefreshContentcommon\n`
	routerContent += `}\n`
	routerContent += `export type H5 = {\n`
	routerContent += `\ttitleNView?: TitleNView\n`
	routerContent += `\tpullToRefresh?: PullToRefresh\n`
	routerContent += `}\n`
	routerContent += `export type PageStyle = {\n`
	routerContent += `\tnavigationBarBackgroundColor?: string\n`
	routerContent += `\tnavigationBarTextStyle?: NavigationBarTextStyle\n`
	routerContent += `\tnavigationBarTitleText?: string\n`
	routerContent += `\tnavigationBarShadow?: NavigationBarShadow\n`
	routerContent += `\tnavigationStyle?: NavigationStyle\n`
	routerContent += `\tbackgroundColor?: string\n`
	routerContent += `\tbackgroundColorContent?: string\n`
	routerContent += `\tenablePullDownRefresh?: boolean\n`
	routerContent += `\tonReachBottomDistance?: number\n`
	routerContent += `\tpageOrientation?: PageOrientation\n`
	routerContent += `\tdisableSwipeBack?: boolean\n`
	routerContent += `\ttitleImage?: string\n`
	routerContent += `\ttransparentTitle?: TransparentTitle\n`
	routerContent += `\ttitlePenetrate?: TitlePenetrate\n`
	routerContent += `\th5?: H5\n`
	routerContent += `\tusingComponents?: UTSJSONObject\n`
	routerContent += `\tleftWindow?: boolean\n`
	routerContent += `\ttopWindow?: boolean\n`
	routerContent += `\trightWindow?: boolean\n`
	routerContent += `\tmaxWidth?: number\n`
	routerContent += `}\n`
	
	routerContent += `export type AnimationType = 'slide-in-right' | 'slide-in-left' | 'slide-in-top' | 'slide-in-bottom' | 'fade-in' | 'zoom-out' | 'zoom-fade-out' | 'pop-in'\n`
	
	routerContent += `export type GlobalStyle = {\n`
	routerContent += `\tnavigationBarBackgroundColor?: string\n`
	routerContent += `\tnavigationBarTextStyle?: NavigationBarTextStyle\n`
	routerContent += `\tnavigationBarTitleText?: string\n`
	routerContent += `\tnavigationStyle?: NavigationStyle\n`
	routerContent += `\tbackgroundColor?: string\n`
	routerContent += `\tbackgroundColorContent?: string\n`
	routerContent += `\tenablePullDownRefresh?: boolean\n`
	routerContent += `\tonReachBottomDistance?: number\n`
	routerContent += `\ttitleImage?: string\n`
	routerContent += `\ttransparentTitle?: TransparentTitle\n`
	routerContent += `\ttitlePenetrate?: TitlePenetrate\n`
	routerContent += `\tpageOrientation?: PageOrientation\n`
	routerContent += `\tanimationType?: AnimationType\n`
	routerContent += `\tusingComponents?: UTSJSONObject\n`
	routerContent += `\tleftWindow?: boolean\n`
	routerContent += `\ttopWindow?: boolean\n`
	routerContent += `\trightWindow?: boolean\n`
	routerContent += `\trpxCalcMaxDeviceWidth?: number\n`
	routerContent += `\trpxCalcBaseDeviceWidth?: number\n`
	routerContent += `\trpxCalcIncludeWidth?: number\n`
	routerContent += `\tmaxWidth?: number\n`
	routerContent += `\th5?: UTSJSONObject\n`
	routerContent += `}\n\n`
	routerContent += `export type IconFont = {\n`
	routerContent += `\ttext?: string\n`
	routerContent += `\tselectedText?: string\n`
	routerContent += `\tfontSize?: string\n`
	routerContent += `\tcolor?: string\n`
	routerContent += `\tselectedColor?: string\n`
	routerContent += `}\n`
	routerContent += `export type TabbarItem = {\n`
	routerContent += `\ticonfont?: IconFont\n`
	routerContent += `\tpagePath?: string\n`
	routerContent += `\ttext?: string\n`
	routerContent += `\ticonPath?: string\n`
	routerContent += `\tselectedIconPath?: string\n`
	routerContent += `\tvisible?: boolean\n`
	routerContent += `}\n`
	routerContent += `export type TabbarMidButton = {\n`
	routerContent += `\twidth?: string\n`
	routerContent += `\theight?: string\n`
	routerContent += `\ttext?: string\n`
	routerContent += `\ticonPath?: string\n`
	routerContent += `\ticonWidth?: string\n`
	routerContent += `\tbackgroundImage?: string\n`
	routerContent += `}\n`
	routerContent += `export type Tabbar = {\n`
	routerContent += `\tcolor?: string\n`
	routerContent += `\tselectedColor?: string\n`
	routerContent += `\tbackgroundColor?: string\n`
	routerContent += `\tborderStyle?: string\n`
	routerContent += `\tblurEffect?: string\n`
	routerContent += `\tlist: TabbarItem[]\n`
	routerContent += `\tfontSize?: string\n`
	routerContent += `\ticonWith?: string\n`
	routerContent += `\tspacing?: string\n`
	routerContent += `\theight?: string\n`
	routerContent += `\tmidButton?: TabbarMidButton\n`
	routerContent += `\ticonfontSrc?: string\n`
	routerContent += `\tbackgroundImage?: string\n`
	routerContent += `\tbackgroundRepeat?: string\n`
	routerContent += `\tredDotColor?: string\n`
	routerContent += `}\n`
	routerContent += `export type MatchMedia = {\n`
	routerContent += `\tminWidth?: number\n`
	routerContent += `}\n`
	routerContent += `export type CommonWindow = {\n`
	routerContent += `\tpath?: string\n`
	routerContent += `\tstyle?: UTSJSONObject\n`
	routerContent += `\tmatchMedia?: MatchMedia\n`
	routerContent += `}\n`
	routerContent += `export type ConditionItem = {\n`
	routerContent += `\tname: string\n`
	routerContent += `\tpath: string\n`
	routerContent += `\tquery?: string\n`
	routerContent += `}\n`
	routerContent += `export type Condition = {\n`
	routerContent += `\tcurrent: number\n`
	routerContent += `\tlist: ConditionItem[]\n`
	routerContent += `}\n`
	routerContent += `export type Easycom = {\n`
	routerContent += `\tautoscan?: boolean\n`
	routerContent += `\tcustom?: UTSJSONObject\n`
	routerContent += `}\n`
	routerContent += `export type UniIdRouter = {\n`
	routerContent += `\tloginPage?: string\n`
	routerContent += `\tresToLogin?: boolean\n`
	routerContent += `\tneedLogin?: string[]\n`
	routerContent += `}\n`
	
	return routerContent
}

function genGlobalStyle (pagesJSON, routerConetnt) {

}

export function genPages (option?: VitePluginOption) {
	const packageJson = require('../../package.json')
	const version = packageJson.version
	const pagesJsonPath = path.resolve(process.env.UNI_INPUT_DIR, './', 'pages.json');
	const pagesJsonContent = fs.readFileSync(pagesJsonPath, 'utf-8');
	// 移除pages.json中的注释
	const jsonWithoutComments = pagesJsonContent.replace(/\/\/.*|\/\*[\s\S]*?\*\//g, '');
	const pagesJson = JSON.parse(jsonWithoutComments);
	
	try {
		const nowDate = getNowDate()
		
		let routerContent = `/**\n`;
		routerContent += `* pages.json映射文件，该文件每次重新编译时都会由插件自动生成，不要直接在该文件内编辑！！！\n`;
		routerContent += `* @author kux <kviewui@163.com>\n`;
		routerContent += `* @created ${formatTime()}\n`;
		routerContent += `* @version ${version}\n`;
		routerContent += `* @copyright Copyright (c) ${nowDate.getFullYear()} The Authors.\n`;
		routerContent += `* @license MIT License\n`;
		routerContent += `* Permission is hereby granted, free of charge, to any person obtaining a copy\n`;
		routerContent += `* of this software and associated documentation files (the "Software"), to deal\n`;
		routerContent += `* in the Software without restriction, including without limitation the rights\n`;
		routerContent += `* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n`;
		routerContent += `* copies of the Software, and to permit persons to whom the Software is\n`;
		routerContent += `* furnished to do so, subject to the following conditions:\n\n`;
		routerContent += `* The above copyright notice and this permission notice shall be included in all\n`;
		routerContent += `* copies or substantial portions of the Software.\n\n`;
		routerContent += `* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n`;
		routerContent += `* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n`;
		routerContent += `* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n`;
		routerContent += `* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n`;
		routerContent += `* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n`;
		routerContent += `* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n`;
		routerContent += `* SOFTWARE.\n`;
		routerContent += `*/\n\n`;
		
		// 遍历 pages.json 生成PagePath
		let Path = '';
		let Name = '';
		let Meta = {};
		
		pagesJson.pages.map(page => {
			Path += `'/${page.path}' | `;
			Name += `'${page.name ?? toPascalCase(page.path)}' | `;
		});
		
		routerContent += `export type PagePath = ${removeLastPipe(Path)};\n\n`;
		routerContent += `export type PageName = ${removeLastPipe(Name)};\n\n`;
		routerContent += `export type PageItem = {\n`;
		routerContent += `\tpath: PagePath\n`;
		routerContent += `\tname?: string\n`;
		routerContent += `\tneedLogin?: boolean\n`
		routerContent += `\tmeta?: UTSJSONObject\n`;
		routerContent += `\tquery?: UTSJSONObject\n`;
		routerContent += `\tdata?: UTSJSONObject\n`;
		routerContent += `\tstyle?: UTSJSONObject\n`
		routerContent += `};\n\n`;
		
		// 定义页面样式类型映射
		routerContent = genPageType(routerContent)
		
		// routerContent += `import { RouteRecordNormalized } from './common/interface.uts';\n\n`;
		routerContent += `export const pages: PageItem[] = [\n`;
		
		// 遍历 pages.json 中的 pages 数组
		pagesJson.pages.map(page => {
			routerContent += `\t{\n`;
			routerContent += `\t\tpath: '/${page.path}',\n`;
			routerContent += `\t\tname: '${page.name ?? toPascalCase(page.path)}',\n`;
			routerContent += `\t\tneedLogin: ${page.needLogin || false},\n`
			routerContent += `\t\tmeta: ${JSON.stringify(page.meta) ?? '{}'},\n`;
			routerContent += `\t\tquery: ${JSON.stringify(page.query) ?? '{}'},\n`;
			routerContent += `\t\tdata: ${JSON.stringify(page.data) ?? '{}'},\n`;
			routerContent += `\t\tstyle: ${JSON.stringify(page.style) ?? '{}'}\n`
			routerContent += `\t},\n`;
			Path += `'/${page.path}' | `;
		});
		routerContent += `];\n\n`;
		
		if (pagesJson.globalStyle) {
			const pagesJsonGlobalStyle = pagesJson.globalStyle
			routerContent += `export const globalStyle = {\n`
			if (pagesJsonGlobalStyle.navigationBarBackgroundColor) {
				routerContent += `\tnavigationBarBackgroundColor: '${pagesJsonGlobalStyle.navigationBarBackgroundColor}',\n`
			}
			if (pagesJsonGlobalStyle.navigationBarTextStyle) {
				routerContent += `\tnavigationBarTextStyle: '${pagesJsonGlobalStyle.navigationBarTextStyle}',\n`
			}
			if (pagesJsonGlobalStyle.navigationStyle) {
				routerContent += `\tnavigationStyle: '${pagesJsonGlobalStyle.navigationStyle}',\n`
			}
			if (pagesJsonGlobalStyle.backgroundColor) {
				routerContent += `\tbackgroundColor: '${pagesJsonGlobalStyle.backgroundColor}',\n`
			}
			if (pagesJsonGlobalStyle.backgroundColorContent) {
				routerContent += `\tbackgroundColorContent: '${pagesJsonGlobalStyle.backgroundColorContent}',\n`
			}
			if (pagesJsonGlobalStyle.enablePullDownRefresh) {
				routerContent += `\tenablePullDownRefresh: ${pagesJsonGlobalStyle.enablePullDownRefresh},\n`
			}
			if (pagesJsonGlobalStyle.onReachBottomDistance) {
				routerContent += `\tonReachBottomDistance: ${pagesJsonGlobalStyle.onReachBottomDistance},\n`
			}
			if (pagesJsonGlobalStyle.titleImage) {
				routerContent += `\ttitleImage: '${pagesJsonGlobalStyle.titleImage}',\n`
			}
			if (pagesJsonGlobalStyle.transparentTitle) {
				routerContent += `\ttransparentTitle: '${pagesJsonGlobalStyle.transparentTitle}',\n`
			}
			if (pagesJsonGlobalStyle.titlePenetrate) {
				routerContent += `\ttitlePenetrate: '${pagesJsonGlobalStyle.titlePenetrate}',\n`
			}
			if (pagesJsonGlobalStyle.pageOrientation) {
				routerContent += `\tpageOrientation: '${pagesJsonGlobalStyle.pageOrientation}',\n`
			}
			if (pagesJsonGlobalStyle.animationType) {
				routerContent += `\tanimationType: '${pagesJsonGlobalStyle.animationType}',\n`
			}
			if (pagesJsonGlobalStyle.usingComponents) {
				routerContent += `\tusingComponents: ${JSON.stringify(pagesJsonGlobalStyle.usingComponents)},\n`
			}
			if (pagesJsonGlobalStyle.leftWindow) {
				routerContent += `\tleftWindow: ${pagesJsonGlobalStyle.leftWindow},\n`
			}
			if (pagesJsonGlobalStyle.topWindow) {
				routerContent += `\ttopWindow: ${pagesJsonGlobalStyle.topWindow},\n`
			}
			if (pagesJsonGlobalStyle.rightWindow) {
				routerContent += `\trightWindow: ${pagesJsonGlobalStyle.rightWindow},\n`
			}
			if (pagesJsonGlobalStyle.rpxCalcMaxDeviceWidth) {
				routerContent += `\trpxCalcMaxDeviceWidth: ${pagesJsonGlobalStyle.rpxCalcMaxDeviceWidth},\n`
			}
			if (pagesJsonGlobalStyle.rpxCalcBaseDeviceWidth) {
				routerContent += `\trpxCalcBaseDeviceWidth: ${pagesJsonGlobalStyle.rpxCalcBaseDeviceWidth},\n`
			}
			if (pagesJsonGlobalStyle.rpxCalcIncludeWidth) {
				routerContent += `\trpxCalcIncludeWidth: ${pagesJsonGlobalStyle.rpxCalcIncludeWidth},\n`
			}
			if (pagesJsonGlobalStyle.maxWidth) {
				routerContent += `\tmaxWidth: ${pagesJsonGlobalStyle.maxWidth},\n`
			}
			if (pagesJsonGlobalStyle.h5) {
				routerContent += `h5: ${JSON.stringify(pagesJsonGlobalStyle.h5)}\n`
			}
			routerContent += `} as GlobalStyle\n\n`
		}
		
		routerContent += `export const hasTabBar = ${pagesJson.tabBar ? true : false}\n`
		if (pagesJson.tabBar) {
			const pageTabBar = pagesJson.tabBar
			routerContent += `export const tabBar = {\n`
			if (pageTabBar.color) {
				routerContent += `\tcolor: '${pageTabBar.color}',\n`
			}
			if (pageTabBar.selectedColor) {
				routerContent += `\tselectedColor: '${pageTabBar.selectedColor}',\n`
			}
			if (pageTabBar.backgroundColor) {
				routerContent += `\tbackgroundColor: '${pageTabBar.backgroundColor}',\n`
			}
			if (pageTabBar.borderStyle) {
				routerContent += `\tborderStyle: '${pageTabBar.borderStyle}',\n`
			}
			if (pageTabBar.blurEffect) {
				routerContent += `\tblurEffect: '${pageTabBar.blurEffect}',\n`
			}
			if (pageTabBar.list) {
				routerContent += `\tlist: [\n`
				pageTabBar.list.map(tabbar => {
					routerContent += `\t\t{\n`
					if (tabbar.iconfont) {
						const iconfont = tabbar.iconfont
						routerContent += `\t\t\ticonfont: {\n`
						if (iconfont.text) {
							routerContent += `\t\t\t\ttext: '${iconfont.text}',\n`
						}
						if (iconfont.selectedText) {
							routerContent += `\t\t\t\tselectedText: '${iconfont.selectedText}',\n`
						}
						if (iconfont.fontSize) {
							routerContent += `\t\t\t\tfontSize: '${iconfont.fontSize}',\n`
						}
						if (iconfont.color) {
							routerContent += `\t\t\t\tcolor: '${iconfont.color}',\n`
						}
						if (iconfont.selectedColor) {
							routerContent += `\t\t\t\tselectedColor: '${iconfont.selectedColor}'\n`
						}
						routerContent += `\t\t\t} as IconFont,\n`
					}
					if (tabbar.pagePath) {
						routerContent += `\t\t\tpagePath: '${tabbar.pagePath}',\n`
					}
					if (tabbar.text) {
						routerContent += `\t\t\ttext: '${tabbar.text}',\n`
					}
					if (tabbar.iconPath) {
						routerContent += `\t\t\ticonPath: '${tabbar.iconPath}',\n`
					}
					if (tabbar.selectedIconPath) {
						routerContent += `\t\t\tselectedIconPath: '${tabbar.selectedIconPath}',\n`
					}
					if (tabbar.visible) {
						routerContent += `\t\t\tvisible: ${tabbar.visible}\n`
					}
					routerContent += `\t\t},\n`
				})
				routerContent += `\t] as TabbarItem[],\n`
			}
			if (pageTabBar.fontSize) {
				routerContent += `\tfontSize: '${pageTabBar.fontSize}',\n`
			}
			if (pageTabBar.iconWidth) {
				routerContent += `\ticonWidth: '${pageTabBar.iconWidth}',\n`
			}
			if (pageTabBar.spacing) {
				routerContent += `\tspacing: '${pageTabBar.spacing}',\n`
			}
			if (pageTabBar.height) {
				routerContent += `\theight: '${pageTabBar.height}',\n`
			}
			if (pageTabBar.midButton) {
				const midButton = pageTabBar.midButton
				routerContent += `\tmidButton: {\n`
				if (midButton.width) {
					routerContent += `\t\twidth: '${midButton.width}',\n`
					routerContent += `\t\theight: '${midButton.height}',\n`
					routerContent += `\t\ttext: '${midButton.text}',\n`
					routerContent += `\t\ticonPath: '${midButton.iconPath}',\n`
					routerContent += `\t\ticonWidth: '${midButton.iconWidth}',\n`
					routerContent += `\t\tbackgroundImage: '${midButton.backgroundImage}'\n`
				}
				routerContent += `\t} as TabbarMidButton,\n`
			}
			if (pageTabBar.iconfontSrc) {
				routerContent += `\ticonfontSrc: '${pageTabBar.iconfontSrc}',\n`
			}
			if (pageTabBar.backgroundImage) {
				routerContent += `\tbackgroundImage: '${pageTabBar.backgroundImage}',\n`
			}
			if (pageTabBar.backgroundRepeat) {
				routerContent += `\tbackgroundRepeat: '${pageTabBar.backgroundRepeat}',\n`
			}
			if (pageTabBar.redDotColor) {
				routerContent += `\tredDotColor: '${pageTabBar.redDotColor}'\n`
			}
			routerContent += `} as Tabbar\n\n`
		}
		
		routerContent += `export const hasTopWindow = ${pagesJson.topWindow ? true : false}\n`
		if (pagesJson.topWindow) {
			const topWindow = pagesJson.topWindow
			routerContent += `export const topWindow = {\n`
			if (topWindow.path) {
				routerContent += `\tpath: '${topWindow.path}',\n`
			}
			if (topWindow.style) {
				routerContent += `\tstyle: ${JSON.stringify(topWindow.style)},\n`
			}
			if (topWindow.matchMedia) {
				routerContent += `\tmatchMedia: {\n`
				routerContent += `\t\tminWidth: ${topWindow.matchMedia.minWidth ?? 768},\n`
				routerContent += `\t} as MatchMedia\n`
			}
			routerContent += `} as CommonWindow\n\n`
		}
		
		routerContent += `export const hasLeftWindow = ${pagesJson.leftWindow ? true : false}\n`
		if (pagesJson.leftWindow) {
			const leftWindow = pagesJson.leftWindow
			routerContent += `export const leftWindow = {\n`
			if (leftWindow.path) {
				routerContent += `\tpath: '${leftWindow.path}',\n`
			}
			if (leftWindow.style) {
				routerContent += `\tstyle: ${JSON.stringify(leftWindow.style)},\n`
			}
			if (leftWindow.matchMedia) {
				routerContent += `\tmatchMedia: {\n`
				routerContent += `\t\tminWidth: ${leftWindow.matchMedia.minWidth ?? 768},\n`
				routerContent += `\t} as MatchMedia\n`
			}
			routerContent += `} as CommonWindow\n\n`
		}
		
		routerContent += `export const hasRightWindow = ${pagesJson.rightWindow ? true : false}\n`
		if (pagesJson.rightWindow) {
			const rightWindow = pagesJson.rightWindow
			routerContent += `export const rightWindow = {\n`
			if (rightWindow.path) {
				routerContent += `\tpath: '${rightWindow.path}',\n`
			}
			if (rightWindow.style) {
				routerContent += `\tstyle: ${JSON.stringify(rightWindow.style)},\n`
			}
			if (rightWindow.matchMedia) {
				routerContent += `\tmatchMedia: {\n`
				routerContent += `\t\tminWidth: ${rightWindow.matchMedia.minWidth ?? 768},\n`
				routerContent += `\t} as MatchMedia\n`
			}
			routerContent += `} as CommonWindow\n\n`
		}
		
		routerContent += `export const hasCondition = ${pagesJson.condition ? true : false}\n`
		if (pagesJson.condition) {
			const condition = pagesJson.condition
			routerContent += `export const condition = {\n`
			routerContent += `\tcurrent: ${condition.current},\n`
			routerContent += `\tlist: [\n`
			condition.list.map(conditionItem => {
				routerContent += `\t\t{\n`
				routerContent += `\t\t\tname: '${conditionItem.name}',\n`
				routerContent += `\t\t\tpath: '${conditionItem.path}',\n`
				if (conditionItem.query) {
					routerContent += `\t\t\tquery: '${conditionItem.query}\n'`
				}
				routerContent += `\t\t}\n`
			})
			routerContent += `\t] as ConditionItem[]\n`
			routerContent += `} as Condition\n\n`
		}
		
		routerContent += `export const hasEasycom = ${pagesJson.easycom ? true : false}\n`
		if (pagesJson.easycom) {
			const easycom = pagesJson.easycom
			routerContent += `export const easycom = {\n`
			if (easycom.autoscan) {
				routerContent += `\tautoscan: ${easycom.autoscan},\n`
			}
			if (easycom.custom) {
				routerContent += `\tcustom: ${JSON.stringify(easycom.custom)}\n`
			}
			routerContent += `} as Easycom\n\n`
		}
		
		routerContent += `export const hasUniIdRouter = ${pagesJson.uniIdRouter ? true : false}\n`
		if (pagesJson.uniIdRouter) {
			const uniIdRouter = pagesJson.uniIdRouter
			routerContent += `export const uniIdRouter = {\n`
			if (uniIdRouter.loginPage) {
				routerContent += `\tloginPage: '${uniIdRouter.loginPage}',\n`
			}
			if (uniIdRouter.resToLogin) {
				routerContent += `\tresToLogin: ${uniIdRouter.resToLogin},\n`
			}
			if (uniIdRouter.needLogin) {
				routerContent += `\tneedLogin: ${JSON.stringify(uniIdRouter.needLogin)}\n`
			}
			routerContent += `} as UniIdRouter\n`
		}
		
		
		// let outputPath = resolvePath(option?.pagesJsonMappingFile ?? './')
		
		// if (isDir(outputPath)) {
		// 	outputPath = path.resolve(outputPath, PAGES_JSON_MAPPING_FILE)
		// }
		const outputPath = resolvePagesJsonOutputPath(option)
		
		autoMkdir(outputPath)
		
		// 写入到router配置文件
		// const outputPath = path.resolve(process.env.UNI_INPUT_DIR, option.pagesJsonMappingFile ?? './pagesJsonRouter.uts');
		// 检查文件是否可写，如果不可写，尝试修改权限
		fs.access(outputPath, fs.constants.F_OK | fs.constants.W_OK, (err) => {
			if (err) {
				if (err.code === 'ENOENT') {
					// 文件不存在，直接写入
					fs.writeFileSync(outputPath, routerContent);
					console.info('pages write complete');
				} else if (err.code === 'EACCES') {
					// 没有写入权限，尝试修改文件权限
					fs.chmod(outputPath, 0o666, (chmodErr) => {
						if (chmodErr) {
							throw chmodErr;
						}
						// 修改权限后再次尝试写入
						fs.writeFileSync(outputPath, routerContent);
						console.info('pages write complete');
					});
				} else {
					throw err;
				}
			} else {
				// 文件可写，直接写入
				fs.writeFileSync(outputPath, routerContent);
				console.info('pages write complete');
			}
		})
	} catch (error) {
		console.error('Error parsing JSON:', error);
		throw error
	}
}

function genComment (title: string) {
	const packageJson = require('../../package.json')
	const version = packageJson.version
	const nowDate = getNowDate()
	
	let content = `/**\n`
	content += `* ${title}\n`
	content += `* @author kux <kviewui@163.com>\n`;
	content += `* @created ${formatTime()}\n`;
	content += `* @version ${version}\n`;
	content += `* @copyright Copyright (c) ${nowDate.getFullYear()} The Authors.\n`;
	content += `* @license MIT License\n`;
	content += `* Permission is hereby granted, free of charge, to any person obtaining a copy\n`;
	content += `* of this software and associated documentation files (the "Software"), to deal\n`;
	content += `* in the Software without restriction, including without limitation the rights\n`;
	content += `* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n`;
	content += `* copies of the Software, and to permit persons to whom the Software is\n`;
	content += `* furnished to do so, subject to the following conditions:\n\n`;
	content += `* The above copyright notice and this permission notice shall be included in all\n`;
	content += `* copies or substantial portions of the Software.\n\n`;
	content += `* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n`;
	content += `* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n`;
	content += `* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n`;
	content += `* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n`;
	content += `* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n`;
	content += `* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n`;
	content += `* SOFTWARE.\n`;
	content += `*/\n\n`;
	
	return content
}

export function genRouter (option?: VitePluginOption) {
	const packageJson = require('../../package.json')
	const version = packageJson.version
	
	try {
		const nowDate = getNowDate()
		
		// let routerContent = ''
		
		// genComment(`路由注册文件，编译时如果该文件不存在会由插件自动生成`, routerContent)
		
		let routerContent = `/**\n`;
		routerContent += `* 路由注册文件，编译时如果该文件不存在会由插件自动生成\n`;
		routerContent += `* @author kux <kviewui@163.com>\n`;
		routerContent += `* @created ${formatTime()}\n`;
		routerContent += `* @version ${version}\n`;
		routerContent += `* @copyright Copyright (c) ${nowDate.getFullYear()} The Authors.\n`;
		routerContent += `* @license MIT License\n`;
		routerContent += `* Permission is hereby granted, free of charge, to any person obtaining a copy\n`;
		routerContent += `* of this software and associated documentation files (the "Software"), to deal\n`;
		routerContent += `* in the Software without restriction, including without limitation the rights\n`;
		routerContent += `* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n`;
		routerContent += `* copies of the Software, and to permit persons to whom the Software is\n`;
		routerContent += `* furnished to do so, subject to the following conditions:\n\n`;
		routerContent += `* The above copyright notice and this permission notice shall be included in all\n`;
		routerContent += `* copies or substantial portions of the Software.\n\n`;
		routerContent += `* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n`;
		routerContent += `* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n`;
		routerContent += `* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n`;
		routerContent += `* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n`;
		routerContent += `* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n`;
		routerContent += `* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n`;
		routerContent += `* SOFTWARE.\n`;
		routerContent += `*/\n\n`;
		
		let routerFile = option?.routerFile ?? `./${ROUTER_FILE}`
		if (isDir(resolvePath(routerFile))) {
			routerFile += `/${ROUTER_FILE}`
		}
		let pagesModulePath = option?.pagesJsonMappingFile ?? `./${PAGES_JSON_MAPPING_FILE}`
		if (isDir(resolvePath(pagesModulePath))) {
			pagesModulePath += `/${PAGES_JSON_MAPPING_FILE}`
		}
		
		routerContent += `import { pages } from '@/${ pagesModulePath }';\n`
		routerContent += `import { RouteRecordNormalized } from '@/uni_modules/kux-router/utssdk/interface';\n`
		routerContent += `\n`
		routerContent += `let routes: RouteRecordNormalized[] = [];\n`
		routerContent += `pages.map((item) => {\n`
		routerContent += `\t// 演示拦截，请根据自己的实际业务逻辑和item内容实现，此处仅作为默认的演示参考\n`
		routerContent += `\tif (item.needLogin == true) {\n`
		routerContent += `\t\t// 这里是自己的拦截逻辑\n`
		routerContent += `\t} else {\n`
		routerContent += `\t\troutes.push({\n`
		routerContent += `\t\t\tpath: item.path,\n`
		routerContent += `\t\t\tname: item.name\n`
		routerContent += `\t\t} as RouteRecordNormalized)\n`
		routerContent += `\t}\n`
		routerContent += `});\n\n`
		routerContent += `export default routes;`
		
		let outputPath = resolvePath(routerFile)
		
		autoMkdir(outputPath)
		
		if (!fs.existsSync(outputPath)) {
			fs.access(outputPath, fs.constants.F_OK | fs.constants.W_OK, (err) => {
				if (err) {
					if (err.code === 'ENOENT') {
						// 文件不存在，直接写入
						fs.writeFileSync(outputPath, routerContent);
						console.info('router write complete');
					} else if (err.code === 'EACCES') {
						// 没有写入权限，尝试修改文件权限
						fs.chmod(outputPath, 0o666, (chmodErr) => {
							if (chmodErr) {
								throw chmodErr;
							}
							// 修改权限后再次尝试写入
							fs.writeFileSync(outputPath, routerContent);
							console.info('router write complete');
						});
					} else {
						throw err;
					}
				} else {
					// 文件可写，直接写入
					fs.writeFileSync(outputPath, routerContent);
					console.info('router write complete');
				}
			})
		}
	} catch (error) {
		console.error('Error parsing JSON:', error);
		throw error
	}
}

export function genInterface (option?: VitePluginOption) {
	let interfaceContent = genComment('路由接口定义文件，该文件由插件自动生成')
	
	interfaceContent += `import * as PagesJson from '@/${resolvePagesJsonOutputPath(option, true)}'\n\n`;
	interfaceContent += `/**\n`
	interfaceContent += ` * 路由名称\n`
	interfaceContent += ` */\n`
	interfaceContent += `export type RouteRecordName = PagesJson.PageName\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 路由地址\n`
	interfaceContent += ` */\n`
	interfaceContent += `export type RouteRecordPath = PagesJson.PagePath\n\n`
	interfaceContent += `export type RouteLocationGuardReturnOptions = {\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 当前路由的 \`query\` 传参\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tquery?: UTSJSONObject\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 当前路由去除 \`query\` 参数后的页面地址\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tpath?: string\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 当前路由隐式传参，即参数不在地址栏中展现\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tdata?: UTSJSONObject\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 路由名称，即 \`routes\` 中配置的 \`name\` 参数\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tname?: RouteRecordName\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 路由元信息，即 \`routes\` 中配置的 \`meta\` 参数\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tmeta?: UTSJSONObject\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 当前路由页面带参数的完整地址，如：\`/pages/user/info?id=1\`\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tfullPath?: string\n`
	interfaceContent += `}\n\n`
	interfaceContent += `export type NavigationGuardReturn = {\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 即将前往的路由信息\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tto?: RouteLocationGuardReturnOptions\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 当前路由信息\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tfrom?: RouteLocationGuardReturnOptions\n`
	interfaceContent += `}\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 导航完成后的规范化路由信息\n`
	interfaceContent += ` */\n`
	interfaceContent += `export type RouteLocationNormalizedLoaded = {\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 当前路由的 \`query\` 传参\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tquery?: UTSJSONObject\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * @deprecated 该属性即将被废弃，请用 \`data\` 替代\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tparams?: UTSJSONObject\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 路由隐式传参，即路由参数不在地址栏中展现的参数，用来替代旧版本的 \`params\`\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tdata?: UTSJSONObject\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 路由名称，即 \`routes\` 中配置的 \`name\` 参数\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tname?: RouteRecordName\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 当前路由页面地址，这个是去除参数后的地址，如：\`/pages/user/info\`\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tpath: string\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * @deprecated 该属性即将被废弃，请用 \`fullPath\` 替代\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tfullUrl?: string\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 该属性替代旧版本的 \`fullUrl\`\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tfullPath?: string\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 路由元信息，即 \`routes\` 中配置的 \`meta\` 参数\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tmeta?: UTSJSONObject\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 从哪个页面跳转过来的\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tfrom?: RouteLocationNormalizedLoaded\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 要到哪个页面去，一般用于路由拦截后完成某些操作再重定向到目标页面的场景\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tto?: RouteLocationNormalizedLoaded\n`
	interfaceContent += `}\n\n`
	interfaceContent += `export type NavigationGuardWithThis = (to: RouteLocationNormalizedLoaded | null, from: RouteLocationNormalizedLoaded | null) => Promise<any | null>\n\n`
	interfaceContent += `export type RouteRecordRedirect = {\n`
	interfaceContent += `\tpath?: string\n`
	interfaceContent += `\tname?: string\n`
	interfaceContent += `}\n\n`
	interfaceContent += `export type RouteRecordRedirectOption = (to: RouteLocationNormalizedLoaded | null) => RouteRecordNormalized | null\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 创建路由时路由表中的路由信息\n`
	interfaceContent += ` */\n`
	interfaceContent += `export type RouteRecordNormalized = {\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 被注册的 \`beforeEnter\` 前置守卫\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tbeforeEnter?: NavigationGuardWithThis\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 路由元信息\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tmeta?: UTSJSONObject\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 路由名称\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tname?: RouteRecordName\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 路由地址\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tpath?: PagesJson.PagePath\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 当前路由的 \`query\` 传参\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tquery?: UTSJSONObject\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 路由隐式传参，替代旧版本的 \`params\`\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tdata?: UTSJSONObject\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 路由重定向\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tredirect?: RouteRecordRedirectOption\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 是否开启启动拦截，开启后 \`beforeEnter\` 和 \`redirect\` 会在实例加载成功后就立刻挂载全局，适用于应用启动拦截的场景，如首页未登录直接跳转登录页等。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tstartupIntercept?: boolean\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 窗口显示的动画类型，\`v1.1.0\` 及以上版本支持\n`
	interfaceContent += `\t * + auto: 自动选择动画效果\n`
	interfaceContent += `\t * + none: 无动画效果\n`
	interfaceContent += `\t * + slide-in-right: 从右侧横向滑动效果\n`
	interfaceContent += `\t * + slide-in-left: 从左侧横向滑动效果\n`
	interfaceContent += `\t * + slide-in-top: 从上侧竖向滑动效果\n`
	interfaceContent += `\t * + slide-in-bottom: 从下侧竖向滑动效果\n`
	interfaceContent += `\t * + fade-in: 从透明到不透明逐渐显示效果\n`
	interfaceContent += `\t * + zoom-out: 从小到大逐渐放大显示效果\n`
	interfaceContent += `\t * + zoom-fade-out: 从小到大逐渐放大并且从透明到不透明逐渐显示效果\n`
	interfaceContent += `\t * + pop-in: 从右侧平移入栈动画效果\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tanimationType?: string\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 窗口显示动画的持续时间，单位为 ms\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tanimationDuration?: number\n`
	interfaceContent += `}\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 创建路由器的配置参数\n`
	interfaceContent += ` */\n`
	interfaceContent += `export type RouterOptions = {\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 创建路由器时的初始化路由表\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\troutes: RouteRecordNormalized[]\n`
	interfaceContent += `}\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 导航失败类型\n`
	interfaceContent += ` * + aborted 被中止，比如路由守卫中手动返回了 \`false\`\n`
	interfaceContent += ` * + cancelled 被取消，比如下一个导航已经开始而导航失败\n`
	interfaceContent += ` * + duplicated 重复导航，比如现在已经处于要导航到的路径而导航失败\n`
	interfaceContent += ` */\n`
	interfaceContent += `export type NavigationFailureType = 'aborted' | 'cancelled' | 'duplicated'\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 导航失败信息\n`
	interfaceContent += ` * + from 当前路由信息\n`
	interfaceContent += ` * + to 即将前往的路由信息\n`
	interfaceContent += ` * + type 导航失败类型\n`
	interfaceContent += ` */\n`
	interfaceContent += `export type NavigationFailure = {\n`
	interfaceContent += `\tfrom: RouteLocationNormalizedLoaded\n`
	interfaceContent += `\tto: RouteLocationNormalizedLoaded\n`
	interfaceContent += `\ttype?: NavigationFailureType\n`
	interfaceContent += `}\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * \`afterEach\` 守卫回调定义\n`
	interfaceContent += ` */\n`
	interfaceContent += `export type NavigationHookAfter = (to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded, failure: NavigationFailure | null) => any\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * \`onError\` 守卫回调定义\n`
	interfaceContent += ` */\n`
	interfaceContent += `export type ErrorListener = (error: any) => void\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 导航时的配置参数\n`
	interfaceContent += ` */\n`
	interfaceContent += `export type RouteLocationNormalizedOptions = {\n`
	interfaceContent += `\tanimationType?: string\n`
	interfaceContent += `\tanimationDuration?: number\n`
	interfaceContent += `}\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 定义一个路由器实例接口\n`
	interfaceContent += ` */\n`
	interfaceContent += `export interface IRouter {\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 创建路由器时的原始选项对象。\n`
	interfaceContent += `\t + \`v1.1.0\` 及以上版本支持\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\treadonly options: RouterOptions | null\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 获取即将离开的路由信息。\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tfrom: RouteLocationNormalizedLoaded | null\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 动态增加 routes 配置中的路由信息。\n`
	interfaceContent += `\t * @param { RouteRecordNormalized } route \`routes\` 中的路由配置信息。\n`
	interfaceContent += `\t * @deprecated 该方法即将被废弃，由路由库提供新的自动化解决方案替代。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\taddRoute (route: RouteRecordNormalized): Promise<any | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 动态更新 routes 配置中的路由信息。\n`
	interfaceContent += `\t * @param { RouteRecordNormalized } route \`routes\` 中的路由配置信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tupdateRoute (route: RouteRecordNormalized): Promise<any | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 获取当前路由信息\n`
	interfaceContent += `\t * @returns 返回一个规范化的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tcurrentRoute (): RouteLocationNormalizedLoaded\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 添加一个导航钩子，它会在每次导航之后被执行。返回一个用来移除该钩子的函数。\n`
	interfaceContent += `\t * @param { NavigationHookAfter } guard 要加入的导航钩子。\n`
	interfaceContent += `\t * @returns 返回一个用来移除该钩子的函数。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tafterEach (guard: NavigationHookAfter): () => void\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 用来移除所有的 \`afterEach\` 钩子函数\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tremoveAfterEach (): void\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 通过调用 uni.navigateBack() 在可能的情况下在历史中后退。相当于 router.go(-1)。\n`
	interfaceContent += `\t * @param { number } [delta=1] 后退的步数。如果 delta 大于现有页面数，则返回到首页\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tback (delta?: number): void\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 通过调用 uni.navigateBack() 在可能的情况下在历史中后退。相当于 router.go(-1)。\n`
	interfaceContent += `\t * @param { number } [delta=1] 后退的步数。如果 delta 大于现有页面数，则返回到首页\n`
	interfaceContent += `\t * @param { RouteLocationNormalizedOptions } options 路由跳转时的配置参数，比如跳转时的转场动画配置\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tback (delta?: number, options?: RouteLocationNormalizedOptions): void\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 添加一个导航钩子，它会在每次导航之前被执行。返回一个用来移除该钩子的函数。\n`
	interfaceContent += `\t * @param { NavigationGuardWithThis } guard 要加入的导航钩子。\n`
	interfaceContent += `\t * @returns 返回一个用来移除该钩子的函数。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tbeforeEach (guard: NavigationGuardWithThis): () => void\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 用来移除所有的 \`beforeEach\` 钩子函数\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tremoveBeforeEach (): void\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 获得所有路由记录的完整列表。\n`
	interfaceContent += `\t * @returns 返回一个路由记录列表。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tgetRoutes (): RouteRecordNormalized[]\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 检查一个给定名称的路由是否存在。\n`
	interfaceContent += `\t * @param { string } name 要检查的路由名称。\n`
	interfaceContent += `\t * @returns 返回一个布尔值，表示路由是否存在。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\thasRoute (name: string): boolean\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 注册一个全局的错误监听器，当路由导航过程中出现错误时，会调用此监听器。\n`
	interfaceContent += `\t * @param { ErrorListener } listener 要注册的错误监听器。\n`
	interfaceContent += `\t * @returns 返回一个用来移除该监听器的函数。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tonError (listener: ErrorListener): void\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 程序式地通过将一条记录加入到历史栈中来导航到一个新的 URL。\n`
	interfaceContent += `\t * @param { RouteRecordPath } to 要导航到的路由地址。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tpush (to: RouteRecordPath): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 程序式地通过将一条记录加入到历史栈中来导航到一个新的 URL。\n`
	interfaceContent += `\t * @param { RouteRecordNormalized } to 要导航到的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tpush (to: RouteRecordNormalized): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 程序式地通过将一条记录加入到历史栈中来导航到一个新的 URL。\n`
	interfaceContent += `\t * @param { any } to 要导航到的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tpush (to: any): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 程序式地通过替换当前的历史记录来导航到一个新的 URL。\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t * @param { RouteRecordPath } to 要导航到的路由地址。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\treplace (to: RouteRecordPath): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 程序式地通过替换当前的历史记录来导航到一个新的 URL。\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t * @param { RouteRecordNormalized } to 要导航到的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\treplace (to: RouteRecordNormalized): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 程序式地通过替换当前的历史记录来导航到一个新的 URL。\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t * @param { any } to 要导航到的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\treplace (to: any): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 关闭所有页面，打开到应用内的某个页面\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t * @param { RouteRecordPath } to 要打开的页面的路由地址。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\treLaunch (to: RouteRecordPath): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 关闭所有页面，打开到应用内的某个页面\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t * @param { RouteRecordNormalized } to 要打开的页面的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\treLaunch (to: RouteRecordNormalized): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 关闭所有页面，打开到应用内的某个页面\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t * @param { any } to 要打开的页面的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\treLaunch (to: any): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t * @param { RouteRecordPath } to 要打开的页面的路由地址。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tswitchTab (to: RouteRecordPath): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t * @param { RouteRecordNormalized } to 要打开的页面的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tswitchTab (to: RouteRecordNormalized): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t * @param { any } to 要打开的页面的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tswitchTab (to: any): Promise<NavigationFailure | null>\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 返回一个路由地址的规范化路由信息。\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t * @param { RouteRecordName } to 路由地址\n`
	interfaceContent += `\t * @returns { RouteLocationNormalizedLoaded } 返回一个规范化的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tresolve (to: RouteRecordName): RouteLocationNormalizedLoaded | null\n\n`
	interfaceContent += `}\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 定义一个管理路由实例接口\n`
	interfaceContent += ` */\n`
	interfaceContent += `export interface IRoute {\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 获取当前所有路由信息\n`
	interfaceContent += `\t * @returns { RouteLocationNormalizedLoaded[] } 返回一个路由记录列表。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tgetRoutes (): RouteLocationNormalizedLoaded[]\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 获取当前路由信息\n`
	interfaceContent += `\t * @returns { RouteLocationNormalizedLoaded } 返回一个规范化的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tcurrent (): RouteLocationNormalizedLoaded\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 根据路由地址或者路由名称判断该路由是否存在\n`
	interfaceContent += `\t * @param { string } nameOrPath 路由地址或者路由名称\n`
	interfaceContent += `\t * @returns { boolean } 返回一个布尔值，表示路由是否存在。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\thasRoute (nameOrPath: string): boolean\n\n`
	interfaceContent += `\t/**\n`
	interfaceContent += `\t * 返回一个路由地址的规范化路由信息。\n`
	interfaceContent += `\t * + \`v1.1.0\` 及以上版本支持。\n`
	interfaceContent += `\t * @param { RouteRecordName } to 路由地址\n`
	interfaceContent += `\t * @returns { RouteLocationNormalizedLoaded } 返回一个规范化的路由信息。\n`
	interfaceContent += `\t */\n`
	interfaceContent += `\tresolve (to: RouteRecordName): RouteLocationNormalizedLoaded | null\n\n`
	interfaceContent += `}\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 返回当前路由器实例\n`
	interfaceContent += ` * @returns { IRoute } 返回当前路由器实例\n`
	interfaceContent += ` */\n`
	interfaceContent += `export declare function useRouter (): IRouter\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 返回当前路由信息\n`
	interfaceContent += ` * @returns { RouteLocationNormalizedLoaded } 返回当前路由规范化的路由信息\n`
	interfaceContent += ` */\n`
	interfaceContent += `export declare function useRoute (): RouteLocationNormalizedLoaded\n\n`
	interfaceContent += `/**\n`
	interfaceContent += ` * 创建一个路由器实例\n`
	interfaceContent += ` * @param { RouterOptions } options 路由器配置\n`
	interfaceContent += ` * @returns { IRouter } 返回一个路由器实例\n`
	interfaceContent += ` */\n`
	interfaceContent += `export declare function createRouter (options: RouterOptions): IRouter\n\n`
	
	try {
		const outputPath = resolvePath(`uni_modules/kux-router/utssdk/interface.uts`)
		
		fs.access(outputPath, fs.constants.F_OK | fs.constants.W_OK, (err) => {
			if (err) {
				if (err.code === 'ENOENT') {
					// 文件不存在，直接写入
					fs.writeFileSync(outputPath, interfaceContent);
					// console.info('router write complete');
				} else if (err.code === 'EACCES') {
					// 没有写入权限，尝试修改文件权限
					fs.chmod(outputPath, 0o666, (chmodErr) => {
						if (chmodErr) {
							throw chmodErr;
						}
						// 修改权限后再次尝试写入
						fs.writeFileSync(outputPath, interfaceContent);
						// console.info('router write complete');
					});
				} else {
					throw err;
				}
			} else {
				// 文件可写，直接写入
				fs.writeFileSync(outputPath, interfaceContent);
				// console.info('router write complete');
			}
		})
	} catch (error) {
		console.error(error)
		throw error
	}
}